import gtk


def _get_filename_from_dialog(title, mode, filters):
    dialog = gtk.FileChooserDialog(title,
        None,
        mode,
        (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK)
    )
    dialog.set_default_response(gtk.RESPONSE_OK)
    for name, ext in filters: 
        filter = gtk.FileFilter()
        filter.set_name(name)
        filter.add_pattern(ext)
        dialog.add_filter(filter)
    
    response = dialog.run()
    if response != gtk.RESPONSE_OK:
        fn = None
    else:
        fn = dialog.get_filename()
    dialog.destroy()
    return fn

def get_filename_for_open(title = "Load file", filters = [("All files", "*")]):
    return _get_filename_from_dialog(title, gtk.FILE_CHOOSER_ACTION_OPEN, filters)

def get_filename_for_save(title = "Save file", filters = [("All files", "*")]):
    return _get_filename_from_dialog(title, gtk.FILE_CHOOSER_ACTION_SAVE, filters)

_message_types = dict(
    info = gtk.MESSAGE_INFO,
    warning = gtk.MESSAGE_WARNING,
    question = gtk.MESSAGE_QUESTION,
    error = gtk.MESSAGE_ERROR,
)

def message_box(message, type = "info", buttons = None):
    mtype = _message_types[type]
    if buttons is None:
        if type == "question":
            buttons = gtk.BUTTONS_YES_NO # gtk.BUTTONS_OK_CANCEL
        else:
            buttons = gtk.BUTTONS_OK
    dialog = gtk.MessageDialog(None, flags=0, type=mtype, buttons=buttons, 
        message_format=message)
    res = dialog.run()
    dialog.destroy()
    if res == gtk.RESPONSE_NONE:
        return None
    if type == "question":
        if res == gtk.RESPONSE_YES:
            return True
        else:
            return False
    else:
        return res

def get_form_input(fields, title = "Form"):
    dialog = gtk.Dialog(title, buttons = (gtk.STOCK_OK, gtk.RESPONSE_OK, 
        gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT))
    inputs = []
    
    def jump_next(obj):
        if obj._index >= len(inputs) - 1:
            dialog.response(gtk.RESPONSE_OK)
        else:
            txt = inputs[obj._index + 1][1]
            txt.grab_focus()
    
    for i, (name, default) in enumerate(fields):
        hbox = gtk.HBox(homogeneous = True)
        hbox2 = gtk.HBox()
        lbl = gtk.Label(name + "    ")
        txt = gtk.Entry()
        hbox2.pack_start(lbl, expand = False, fill = False)
        if default:
            txt.set_text(default)
        inputs.append((name, txt))
        txt._index = i
        txt.connect("activate", jump_next)
        hbox.pack_start(hbox2)
        hbox.pack_start(txt)
        dialog.vbox.pack_start(hbox)
    
    dialog.show_all()
    res = dialog.run()
    if res == gtk.RESPONSE_OK:
        results = dict((name, obj.get_text()) for name, obj in inputs)
    else:
        results = None
    dialog.destroy()
    return results


def get_input(message, default = "", title = "Input"):
    results = get_form_input([(message, default)], title = title)
    if results:
        return results[message]
    else:
        return None


if __name__ == "__main__":
    print get_form_input([
         ("What is your name?", "Lancelot"), 
         ("What is quest?", "To seek the holy grail"), 
         ("What is your favorite color?", "blue")
     ])

















